﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Landscape.Business.Common
{

    public class GUIDField
    {
        public Guid OracleGUID { get; set; }
        public Guid Value { get; private set; }

        private GUIDField(byte[] gByte, bool isMicrosoftGuid)
        {
            if (isMicrosoftGuid)
            {
                Value = new Guid(gByte);
                SwapArrayElements(gByte);
                OracleGUID = new Guid(gByte);
            }
            else
            {
                OracleGUID = new Guid(gByte);
                SwapArrayElements(gByte);
                Value = new Guid(gByte);
            }
        }

        //Convertion from one to other, doesn't matter which one it is at the moment the function is called
        //the elements are not touching each other, so this method can be used both ways
        private void SwapArrayElements(byte[] gByte)
        {
            //Microsoft { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
            //Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

            //Oracle { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            gByte.Swap(0, 3);
            //Oracle { 3, 1, 2, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            gByte.Swap(1, 2);
            //Oracle { 3, 2, 1, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            gByte.Swap(4, 5);
            //Oracle { 3, 2, 1, 0, 5, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            gByte.Swap(6, 7);
            //Oracle { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
        }

        public byte[] ToOracleByteArray()
        {
            return this.OracleGUID.ToByteArray();
        }

        public string ToLDAPString()
        {
            return this.Value.ToString().Replace("-", "");
        }

        public string ToOracleString()
        {
            return this.OracleGUID.ToString().Replace("-", "");
        }

        public override string ToString()
        {
            return this.ToLDAPString();
        }

        public static GUIDField CreateFromOracleByteArray(byte[] gByte)
        {
            GUIDField id = new GUIDField(gByte, false);
            return id;
        }

        public static GUIDField CreateFromMicrosoftByteArray(byte[] gByte)
        {
            GUIDField id = new GUIDField(gByte, true);
            return id;
        }

        public static GUIDField CreateFromMicrosoftGuid(Guid g)
        {
            GUIDField id = new GUIDField(g.ToByteArray(), true);
            return id;
        }

        public static GUIDField CreateFromLDAPGuidString(string id)
        {
            Guid g = ConvertToGuid(id);
            if (g.Equals(Guid.Empty))
                return null;
            else
                return GUIDField.CreateFromMicrosoftGuid(g);
        }

        private static Guid ConvertToGuid(string s)
        {
            if (!string.IsNullOrEmpty(s))
            {
                try
                {
                    //covert to guid
                    return new Guid(s);
                }
                catch
                {
                    //not guid
                }
            }
            return Guid.Empty;
        }
    }
    public static class Extensions
    {
        public static void Swap(this byte[] array, int i1, int i2)
        {
            byte temp = array[i1];
            array[i1] = array[i2];
            array[i2] = temp;
        }
    }
}
